import json
import logging
from typing import Dict, Any, Tuple, List

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class DifyTextOutputNode:
    """
    专门为Dify集成设计的ComfyUI文本输出节点
    确保输出格式符合Dify工作流的要求
    """
    
    @classmethod
    def INPUT_TYPES(cls):
        """定义节点的输入类型"""
        return {
            "required": {
                "text": ("STRING", {
                    "multiline": True,
                    "default": "",
                    "forceInput": True,  # 强制从其他节点接收输入
                    "tooltip": "要输出到Dify的文本内容"
                }),
                "format_for_dify": ("BOOLEAN", {
                    "default": True,
                    "tooltip": "是否格式化为Dify期望的JSON格式"
                }),
                "include_metadata": ("BOOLEAN", {
                    "default": False,
                    "tooltip": "是否包含元数据信息"
                })
            },
            "optional": {
                "additional_data": ("STRING", {
                    "multiline": True,
                    "default": "[]",
                    "tooltip": "附加的JSON数据（可选）"
                })
            }
        }

    RETURN_TYPES = ("STRING", "STRING")  # 返回两个字符串输出
    RETURN_NAMES = ("dify_output", "raw_text")
    
    FUNCTION = "process_text_output"
    CATEGORY = "Dify Integration"
    
    OUTPUT_NODE = True  # 标记为输出节点
    
    def process_text_output(self, text="", format_for_dify=True, 
                          include_metadata=False, additional_data="[]"):
        """
        处理文本输出，格式化为Dify期望的格式
        
        Args:
            text: 要输出的文本内容
            format_for_dify: 是否格式化为Dify格式
            include_metadata: 是否包含元数据
            additional_data: 附加的JSON数据
            
        Returns:
            Tuple[str, str]: 格式化的Dify输出和原始文本
        """
        try:
            # 确保text是字符串类型
            if not isinstance(text, str):
                text = str(text)
                
            logger.info(f"[DifyTextOutputNode] 处理文本输出: {text[:100]}...")
            
            # 解析附加数据
            try:
                parsed_additional_data = json.loads(additional_data) if additional_data.strip() else []
            except json.JSONDecodeError:
                logger.warning(f"附加数据JSON格式错误，使用空数组: {additional_data}")
                parsed_additional_data = []

            if format_for_dify:
                # 创建完全符合Dify期望的输出格式
                dify_output = {
                    "text": text,
                    "files": [],
                    "json": [
                        {
                            "data": parsed_additional_data
                        }
                    ]
                }
                
                # 如果需要包含元数据
                if include_metadata:
                    dify_output["metadata"] = {
                        "node_type": "DifyTextOutputNode",
                        "processing_time": self._get_current_timestamp(),
                        "text_length": len(text),
                        "format_version": "1.0"
                    }
                
                # 转换为JSON字符串
                dify_json_output = json.dumps(dify_output, ensure_ascii=False, indent=2)
                
                logger.info(f"[DifyTextOutputNode] Dify格式输出生成成功")
                return (dify_json_output, text)
            else:
                # 直接返回原始文本
                logger.info(f"[DifyTextOutputNode] 返回原始文本")
                return (text, text)
                
        except Exception as e:
            error_message = f"处理文本输出时出错: {str(e)}"
            logger.error(f"[DifyTextOutputNode] {error_message}")
            
            # 返回错误信息，但保持Dify格式
            error_output = {
                "text": f"错误: {error_message}",
                "files": [],
                "json": [
                    {
                        "data": [{"error": error_message}]
                    }
                ]
            }
            
            return (json.dumps(error_output, ensure_ascii=False), f"错误: {error_message}")
    
    def _get_current_timestamp(self):
        """获取当前时间戳"""
        import datetime
        return datetime.datetime.now().isoformat()

class TextDisplayNode:
    """
    文本显示节点，用于在ComfyUI界面中显示文本内容
    """
    
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "text": ("STRING", {
                    "multiline": True,
                    "default": "",
                    "forceInput": True
                })
            }
        }

    RETURN_TYPES = ("STRING",)
    RETURN_NAMES = ("text",)
    FUNCTION = "display_text"
    CATEGORY = "Dify Integration"
    
    OUTPUT_NODE = True
    
    def display_text(self, text=""):
        """显示文本内容"""
        logger.info(f"[TextDisplayNode] 显示文本: {text}")
        print(f"Text Display: {text}")
        return (text,)

class TextCombineNode:
    """
    文本组合节点，用于组合多个文本输入
    """
    
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "text1": ("STRING", {
                    "multiline": True,
                    "default": "",
                    "tooltip": "第一个文本输入"
                }),
            },
            "optional": {
                "text2": ("STRING", {
                    "multiline": True,
                    "default": "",
                    "tooltip": "第二个文本输入"
                }),
                "text3": ("STRING", {
                    "multiline": True,
                    "default": "",
                    "tooltip": "第三个文本输入"
                }),
                "separator": ("STRING", {
                    "default": " ",
                    "tooltip": "分隔符"
                })
            }
        }

    RETURN_TYPES = ("STRING",)
    RETURN_NAMES = ("combined_text",)
    FUNCTION = "combine_texts"
    CATEGORY = "Dify Integration"
    
    def combine_texts(self, text1="", text2="", text3="", separator=" "):
        """组合多个文本"""
        texts = [t for t in [text1, text2, text3] if t.strip()]
        combined = separator.join(texts)
        
        logger.info(f"[TextCombineNode] 组合文本: {combined[:100]}...")
        return (combined,)

# 节点映射
NODE_CLASS_MAPPINGS = {
    "DifyTextOutputNode": DifyTextOutputNode,
    "TextDisplayNode": TextDisplayNode,
    "TextCombineNode": TextCombineNode
}

NODE_DISPLAY_NAME_MAPPINGS = {
    "DifyTextOutputNode": "Dify Text Output",
    "TextDisplayNode": "Text Display",
    "TextCombineNode": "Text Combine"
} 